package com.sunwayhorizo.health.business.registries.employee;

import static com.sunwayhorizo.health.hl7.vocabulary.RoleIICode.EMPLOYEEID;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.ejb.Stateless;

import org.jboss.seam.Component;
import org.jboss.seam.annotations.Name;

import com.sunwayhorizo.health.business.base.BaseManager;
import com.sunwayhorizo.health.business.dto.ResultsDTO;
import com.sunwayhorizo.health.business.dto.patad.empi.PatientBaseInfoDTO;
import com.sunwayhorizo.health.business.dto.registries.DepartmentDTO;
import com.sunwayhorizo.health.business.dto.registries.EntitysDTO;
import com.sunwayhorizo.health.business.dto.registries.OrganizationDTO;
import com.sunwayhorizo.health.business.registries.employee.query.EmployeeQueryLocal;
import com.sunwayhorizo.health.business.registries.organization.DepartmentManagerLocal;
import com.sunwayhorizo.health.business.registries.organization.OrganizationManagerLocal;
import com.sunwayhorizo.health.business.registries.organization.query.DepartmentQueryLocal;
import com.sunwayhorizo.health.business.registries.organization.query.OrganizationQueryLocal;
import com.sunwayhorizo.health.business.registries.person.PersonManagerLocal;
import com.sunwayhorizo.health.common.DataTypeUtil;
import com.sunwayhorizo.health.common.ListUtil;
import com.sunwayhorizo.health.common.StrUtil;
import com.sunwayhorizo.health.hl7.common.Hl7Exception;
import com.sunwayhorizo.health.hl7.datatypes.CE;
import com.sunwayhorizo.health.hl7.datatypes.ED;
import com.sunwayhorizo.health.hl7.datatypes.II;
import com.sunwayhorizo.health.hl7.datatypes.SET_II;
import com.sunwayhorizo.health.hl7.persistent.RimCoreRoleLink;
import com.sunwayhorizo.health.hl7.rim.ControlAct;
import com.sunwayhorizo.health.hl7.rim.Employee;
import com.sunwayhorizo.health.hl7.rim.Organization;
import com.sunwayhorizo.health.hl7.rim.Person;
import com.sunwayhorizo.health.hl7.rim.Role;
import com.sunwayhorizo.health.hl7.rim.Rolelink;
import com.sunwayhorizo.health.hl7.vocabulary.ActCode;
import com.sunwayhorizo.health.hl7.vocabulary.ParticipationType;
import com.sunwayhorizo.health.hl7.vocabulary.RoleClass;
import com.sunwayhorizo.health.hl7.vocabulary.RoleCode;
import com.sunwayhorizo.health.hl7.vocabulary.RoleIICode;
import com.sunwayhorizo.health.hl7.vocabulary.RoleLinkType;

/**
 * @Title: EmployeeManager
 * @Package com.sunwayhorizo.health.business.registries
 * @Description: 员工登记sessionBean
 * @version V1.0
 * @firstAuthor jinzw
 * @firstTime 2010-12-07 下午09:36:59
 * @lastAuthor jinzw
 * @lastTime 2011-07-05 下午09:36:59
 */

@Name("EmployeeManager")
@Stateless
public class EmployeeManager extends BaseManager implements EmployeeManagerLocal
{

    // 注入员工关联的seam组件
    private OrganizationQueryLocal organizationQuery = (OrganizationQueryLocal) Component.getInstance("OrganizationQuery");
    private PersonManagerLocal personManager = (PersonManagerLocal) Component.getInstance("PersonManager");
    private DepartmentQueryLocal departmentQuery = (DepartmentQueryLocal) Component.getInstance("DepartmentQuery");
    private DepartmentManagerLocal departmentManager = (DepartmentManagerLocal) Component.getInstance("DepartmentManager");
    private EmployeeQueryLocal empQuery = (EmployeeQueryLocal) Component.getInstance("EmployeeQuery");


    public ResultsDTO newEmployee(EntitysDTO entityDTO) throws Hl7Exception
    {
        if (entityDTO == null)
        {
            log.info("EmployeeManager-newEmployee-entityDTO信息为空");
            return this.getResultsDTO("员工信息为空", true, null);
        }
        // 初始化基础数据
        String extenID = em.createNativeQuery("select EXTEN_CODE.NEXTVAL from dual").getResultList().get(0).toString();
        SET_II id = DataTypeUtil.getSet_II(root, extenID, null, "employee");
        
        // 定义员工关联的对象
        Person person = null;
        Employee employee = null;
        Role organizationRole = null;
        Organization department = null;
        List<Role> workGroupList = new ArrayList<Role>();
        
        // 查询员工机构关联实例对象
        organizationRole = organizationQuery.findRoleByEntityId(entityDTO.getOrganization().getOrgId());
        //查询员工工作组
        if (ListUtil.isNotEmpty(entityDTO.getWorkgroupIds()))
        {
            for (String workGroupId : entityDTO.getWorkgroupIds())
            {
                Role role = baseQuery.findRoleById(Long.parseLong(workGroupId));
                workGroupList.add(role);
            }
        }
        else
        {
            if (ListUtil.isNotEmpty(entityDTO.getWorkgroupCodes()))
            {
                for (String workGroupCode : entityDTO.getWorkgroupCodes())
                {
                    Role workGroupRole = departmentQuery.findWorkGroupRoleByWorkGroupCode(workGroupCode);
                    workGroupList.add(workGroupRole);
                }
            }
        }
        // 查找系统是否有person存在
        if (StrUtil.isNotEmpty(entityDTO.getPatientBaseInfo().getNatureName()))
        {
            String sex = entityDTO.getPatientBaseInfo().getNatureSexDic().getConceptCode();
            person = personManager.findSamePerson(entityDTO.getPatientBaseInfo().getNatureName(), sex, "");
        }
        if (null == person)
        {
            person = personManager.newPerson(entityDTO);
        }
        // 查询员工部门信息
        if (StrUtil.isNotEmpty(entityDTO.getDepartment().getDepartmentId()))
        {
            department = (Organization) baseQuery.findHl7EntityById(Long.valueOf(entityDTO.getDepartment().getDepartmentId()));
        }

        // 创建员工角色
        CE duty = DataTypeUtil.getCE(entityDTO.getPatientBaseInfo().getDutyDic().getConceptCode());
        employee = this.getRoleFactory().newEmployee(duty, person, department, id);

        // 添加员工RIM角色信息
        converEmployeeToDto(employee, entityDTO);
        
        ControlAct controlAct = newControlAct(ActCode.EMPLOYEE, ParticipationType.SBJ, extenID, employee);

        // 对员工角色和工作组角色加入rolelink
        if (ListUtil.isNotEmpty(workGroupList))
        {
            for (Role workGroupRole : workGroupList)
            {
                employee.addTargetRoleLink(RoleLinkType.CONT, workGroupRole, DataTypeUtil.getCS(null), DataTypeUtil.getCS(null),
                    DataTypeUtil.getINT((1L)));
            }
        }
        
        // 对员工角色和单位角色加入rolelink
        if (null != organizationRole)
        {
            employee.addTargetRoleLink(RoleLinkType.CONT, organizationRole, DataTypeUtil.getCS(null), DataTypeUtil.getCS(null),
                DataTypeUtil.getINT((1L)));
        }

        save(controlAct);
       
        log.info("员工信息保存成功"+employee.getRoleId().toString());
        return this.getResultsDTO("员工信息保存成功", true, employee.getRoleId().toString());
    }


    public ResultsDTO updateEmployee(EntitysDTO entityDTO) throws Hl7Exception
    {
        if (StrUtil.isEmpty(entityDTO.getPatientBaseInfo().getPersonId()))
            return this.getResultsDTO("修改失败,员工id为空", true, null);

        // 根据员工角色id拿到员工角色信息
        Employee employee = (Employee) baseQuery.findRoleById(Long.valueOf(entityDTO.getPatientBaseInfo().getPersonId()));
        
        // 修改工作组信息
        modifyWorkGroup(employee, entityDTO.getWorkgroupIds());
        
        // 修改员工基本信息
        Person person = (Person) employee.getPlayerEntities();
        personManager.modifyPerson(person, entityDTO);
        
        // 修改员工角色信息
        converEmployeeToDto(employee, entityDTO);
        update(employee);
//        em.merge(employee);
        
        log.info(employee.getRoleId() + "员工修改成功");
        return this.getResultsDTO("修改成功", true, null);
    }


    @SuppressWarnings({ "rawtypes", "unused" })
    public ResultsDTO delEmployee(List empIds) throws Hl7Exception
    {
        for (int i = 0; i < empIds.size(); i++)
        {
            String roleId = (String) empIds.get(i);
            Employee employee = (Employee) baseQuery.findRoleById(Long.parseLong(roleId));
            em.remove(employee);
            log.info("删除" + employee.getRoleId() + "员工成功");
            return this.getResultsDTO("删除成功", true, null);
        }
        return this.getResultsDTO("删除失败", false, null);
    }


    public ResultsDTO findEmployeeByDept(int currentPage, int pageSize, String name, String departmentId) throws Hl7Exception
    {
        List<Role> list = empQuery.findEmpByDeptIdAndPage(currentPage, pageSize, name, departmentId);
        List<EntitysDTO> entityList = findEntitysDTOListByList(list);
        if (ListUtil.isNotEmpty(entityList))
        {
            log.info("查询" + list.size() + "个员工");
            dto = new ResultsDTO();
            dto.setObject(entityList);
            dto.setTotalRecords(empQuery.findEmployeeCount(name, departmentId, null));
            dto.setResultFlag(true);
            dto.setResultDesc("查询成功");
            return dto;
        }
        else
        {
            return getResultsDTO("没有找到记录", true, null);
        }
    }


    public ResultsDTO findEmployeeByWorkGroup(int currentPage, int pageSize, String name, String workGroupId) throws Hl7Exception
    {
        List<Role> list = empQuery.findEmployeeByWorkGroup(currentPage, pageSize, name, workGroupId);
        List<EntitysDTO> entityList = findEntitysDTOListByList(list);
        if (ListUtil.isNotEmpty(entityList))
        {
            log.info("查询" + list.size() + "个员工");
            dto = new ResultsDTO();
            dto.setObject(entityList);
            dto.setTotalRecords(empQuery.findEmployeeCount(name, null, workGroupId));
            dto.setResultFlag(true);
            dto.setResultDesc("查询成功");
            return dto;
        }
        else
        {
            return this.getResultsDTO("没有找到记录", true, null);
        }
    }

    public ResultsDTO findEmpList(String departmentId) throws Hl7Exception
    {
        List<Role> empList = empQuery.findEmployeeList(0, null, departmentId);
        List<EntitysDTO> list = findEntitysDTOListByList(empList);
        if (ListUtil.isNotEmpty(list))
        {
            dto = new ResultsDTO();
            dto.setResultFlag(true);
            dto.setPageSize(list.size());
            dto.setObject(list);
            log.info("该科室下有" + list.size() + "个员工");
            return dto;
        }
        else
        {
            log.info("没有找到该科室下面的员工");
            return this.getResultsDTO("没有找到该科室下面的员工", true, null);
        }
    }


    @SuppressWarnings("rawtypes")
    public ResultsDTO findEmployeeList(String departmentId, String dicCode) throws Hl7Exception
    {
        List empList = empQuery.findEmpByDeptOrDicCode(departmentId, dicCode);
        if (ListUtil.isNotEmpty(empList))
        {
            Object[][] objs = new Object[empList.size()][2];
            for (int i = 0; i < empList.size(); i++)
            {
                Object[] obj = (Object[]) empList.get(i);
                objs[i] = new Object[] { obj[0], obj[1],obj[2] };
            }
            return this.getResultsDTO("成功得到该科室下的医生", true, objs);
        }
        return this.getResultsDTO("该科室下面没有医生", true, null);
    }


    @SuppressWarnings("rawtypes")
    public ResultsDTO findEmpList(String workGroupId, String dicCode) throws Hl7Exception
    {
        if(StrUtil.isNotEmpty(dicCode)) dicCode = dicCode.toUpperCase();
        List list = empQuery.findEmployeeByWGId(workGroupId, dicCode);
        if (ListUtil.isNotEmpty(list))
        {
            Object[][] objs = new Object[list.size()][2];
            for (int i = 0; i < list.size(); i++)
            {
                Object[] obj = (Object[]) list.get(i);
                objs[i] = new Object[] { obj[0], obj[1] };
            }

            return this.getResultsDTO("成功得到该工作组下的医生", true, objs);
        }
        return this.getResultsDTO("该工作组下面没有医生", true, null);
    }


    public Employee findEmployeeDetail(long roleId, String empId) throws Hl7Exception
    {
        List<Role> empList = empQuery.findEmployeeList(roleId, empId, null);
        if (ListUtil.isNotEmpty(empList))
        {
            return (Employee) empList.get(0);
        }
        return null;
    }


    public PatientBaseInfoDTO findPlayEntityByRoleId(long roleId) throws Hl7Exception
    {
        Employee emp = findEmployeeDetail(roleId, null);
        return findPlayEntityByRole(emp);
    }

    public PatientBaseInfoDTO findPlayEntityByRole(Role role) throws Hl7Exception
    {
        if (null == role)  return null;
        if (role.getClassCode().code().toString().equals(RoleClass.EMP.code().toString()))
        {
            Employee emp = (Employee) role;
            Person person = (Person) emp.getPlayerEntities();

            PatientBaseInfoDTO patientBaseInfo = null;
            if (person != null)
            {
                patientBaseInfo = personManager.constructorPatBaseInfo(person);
            }

            //职务
            patientBaseInfo.setDutyDic(getDictionaryFactory().getDictionaryDTOByCe(emp.getJobCode()));
            //职称
            patientBaseInfo.setTitleDic(getDictionaryFactory().getDictionaryDTOByCe(emp.getJobTitleName()));
            // 员工编码
            patientBaseInfo.setNatureId((ListUtil.isNotEmpty(emp.getRoleIiList()) ? emp.getRoleIiList().get(0).getExtensionTxt() : ""));
            patientBaseInfo.setPersonId(String.valueOf(emp.getRoleId()));// 员工ID
            return patientBaseInfo;
        }
        return null;
    }


    public DepartmentDTO findScopeEntityByRole(long roleId) throws Hl7Exception
    {
        Employee emp = findEmployeeDetail(roleId, null);
        return findScopeEntityByRole(emp);
    }


    public DepartmentDTO findScopeEntityByRole(Role role) throws Hl7Exception
    {
        if (role.getClassCode().code().toString().equals(RoleClass.EMP.code().toString()))
        {
            Employee emp = (Employee) role;
            return departmentManager.convertDepartmentDTO((Organization)emp.getScoperEntities());
        }
        return null;
    }


    public OrganizationDTO findOrganizationByRole(long roleId) throws Hl7Exception
    {
        Employee emp = findEmployeeDetail(roleId, null);
        return findOrganizationByRole(emp);
    }

    public OrganizationDTO findOrganizationByRole(Role role) throws Hl7Exception
    {
        log.info("调用的是findOrganizationByRole方法");
        if (role.getClassCode().code().toString().equals(RoleClass.EMP.code().toString()))
        {
            Employee emp = (Employee) role;
            List<Rolelink> list =emp.getSourceRolelinks();
            OrganizationManagerLocal organizationManager = (OrganizationManagerLocal) Component.getInstance("OrganizationManager");
            if (ListUtil.isNotEmpty(list))
            {
                for (Rolelink roleLink : list)
                {
                    if (roleLink.getTargetRole().getCode().code().equals(RoleCode.HOSPITAL.code()))
                    {
                        return organizationManager.converOrganizationDtoToOrgRole((Role)roleLink.getTargetRole());
                    }
                }
            }
        }
        return null;
    }


    public List<DepartmentDTO> findWorkGroupByRoleId(long roleId) throws Hl7Exception
    {
        log.info("调用的是findWorkGroupByRoleId方法");
        Employee emp = findEmployeeDetail(roleId, null);
        return  findWorkGroupByRole(emp);
    }
    
    public List<DepartmentDTO> findWorkGroupByRole(Role role) throws Hl7Exception
    {
        log.info("调用的是findWorkGroupByRole方法");
        if (role == null) return null;
       
        List<DepartmentDTO> workGroupList = new ArrayList<DepartmentDTO>();
        Employee emp = (Employee) role;
        if(em.contains(emp))
        {
            //查询需要更新缓存
            em.refresh(emp);
        }
        List<Rolelink> list =emp.getSourceRolelinks();
        DepartmentManagerLocal departmentManager = (DepartmentManagerLocal) Component.getInstance("DepartmentManager");
        if (ListUtil.isNotEmpty(list))
        {
            for (RimCoreRoleLink roleLink : list)
            {
                if (roleLink.getTargetRole().getCode().code().equals(RoleCode.WORKGROUP.code()))
                {
                    DepartmentDTO departmentDTO = departmentManager.convertDepartmentDTO((Organization)roleLink.getTargetRole().getPlayerEntities());
                    departmentDTO.setRimDepartmentRoleId(String.valueOf(roleLink.getTargetRole().getRoleId()));
                    // 拿到科室code
                    Role workGroupRole = (Role)roleLink.getTargetRole();
                    II ii = workGroupRole.getId(RoleIICode.DEPTCODE);
                    departmentDTO.setDepartmentCode( ii != null && ii.extension()!=null ? ii.extension().toString() : null);
                    workGroupList.add(departmentDTO);
                }
            }
        }
        return workGroupList;
    }


    public List<String> findWorkGroupIdsByRole(Role role) throws Hl7Exception
    {
        if (role == null)  return null;
        List<DepartmentDTO> list = findWorkGroupByRole(role);
        if (ListUtil.isEmpty(list))
            return null;
        List<String> workGroupids = new ArrayList<String>();
        for (DepartmentDTO departmentDTO : list)
        {
            workGroupids.add(departmentDTO.getRimDepartmentRoleId());
        }
        log.info(workGroupids);
        return workGroupids;
    }


    @SuppressWarnings({ "unchecked", "rawtypes" })
    public Map findEntityByRole(long roleId) throws Hl7Exception
    {
        log.info("调用的是findEntityByRole方法");
        Map<String, Object> map = new HashMap<String, Object>();
        Employee emp = findEmployeeDetail(roleId, null);
        if (emp == null)
            return map;
        map.put("PatientBaseInfo", findPlayEntityByRole(emp));
        map.put("Department", findScopeEntityByRole(emp));
        map.put("Organization", findOrganizationByRole(emp));
        map.put("WorkGroup", findWorkGroupByRole(emp));
        return map;
    }


    @SuppressWarnings({ "unchecked", "rawtypes" })
    public Map findEntityByRole(Role role) throws Hl7Exception
    {
        log.info("调用的是findEntityByRole方法");
        Map<String, Object> map = new HashMap<String, Object>();
        if (role == null) return map;
        map.put("PatientBaseInfo", findPlayEntityByRole(role));
        map.put("Department", findScopeEntityByRole(role));
        map.put("Organization", findOrganizationByRole(role));
        map.put("WorkGroup", findWorkGroupByRole(role));
        return map;
    }


    @Override
    public ResultsDTO validateExsit(String employId) throws Hl7Exception
    {
        List<Employee> employees = empQuery.validateExsit(employId);
        if (ListUtil.isNotEmpty(employees))
        {
            log.info("ResultsDTO-validateExsit-员工已存在");
            return getResultsDTO("员工已存在", true, true);
        }
        else
        {
            log.info("ResultsDTO-validateExsit-员工不存在");
            return getResultsDTO("员工不存在", true, false);
        }
    }


    //设置员工角色信息
    private void converEmployeeToDto(Employee employee, EntitysDTO entityDTO) throws Hl7Exception
    {
        // 员工编码
        II empCode = DataTypeUtil.getII(root, entityDTO.getPatientBaseInfo().getNatureId(), EMPLOYEEID.toString());
        employee.setId(empCode);
        // 添加医生电子签名
        employee.setProtectiveEquipmentText(DataTypeUtil.getED("", entityDTO.getPatientBaseInfo().getSignImg()));
        
        if (null != entityDTO.getPatientBaseInfo().getDutyDic()
                && StrUtil.isNotEmpty(entityDTO.getPatientBaseInfo().getDutyDic().getConceptCode()))
        {
            // 员工职务
            CE duty = getDictionaryFactory().getCeByDictionaryDTO(entityDTO.getPatientBaseInfo().getDutyDic());
            employee.setJobCode(duty);
        }
        if (null != entityDTO.getPatientBaseInfo().getTitleDic()
                && StrUtil.isNotEmpty(entityDTO.getPatientBaseInfo().getTitleDic().getConceptCode()))
        {
            // 员工职称
            CE title = getDictionaryFactory().getCeByDictionaryDTO(entityDTO.getPatientBaseInfo().getTitleDic());
            employee.setJobTitleName(title);
        }
        
        // 员工所属科室
        Organization department = (Organization) employee.getScoperEntity();
        if(entityDTO.getDepartment() != null)
        {
            if(!String.valueOf((department != null ? department.getEntityId() : 0)).equals(entityDTO.getDepartment().getDepartmentId()))
            {
                Organization newDepartment = (Organization) baseQuery.findHl7EntityById(Long.valueOf(entityDTO.getDepartment().getDepartmentId()));
                employee.setScoperEntity(newDepartment);
            }
        }
       

    }


   //修改员工工作组信息
    private void modifyWorkGroup(Employee emp, List<String> workGroupIds) throws Hl7Exception
    {
        if (null == emp)  return;
        List<String> newWorkGroupIds = workGroupIds;
        List<RimCoreRoleLink> delWorkGroupIds = new ArrayList<RimCoreRoleLink>();
        List<Rolelink> roleLinklist = emp.getSourceRolelinks();
            for (RimCoreRoleLink roleLink : roleLinklist)
            {
                if (roleLink.getTargetRole().getCode().code().equals(RoleCode.WORKGROUP.code()))
                {
                    int flag = 0;
                    long workGroupId = roleLink.getTargetRole().getRoleId();
                    if (ListUtil.isNotEmpty(newWorkGroupIds))
                    {
                        for (String newWorkGroupId : newWorkGroupIds)
                        {
                            long newId = Long.parseLong(newWorkGroupId);
                            if (newId == workGroupId)
                            {
                                newWorkGroupIds.remove(newWorkGroupId);
                                flag = 1;
                                break;
                            }
                        }
                    }
                    if (flag == 0)
                    {
                        delWorkGroupIds.add(roleLink);
                    }
                }
            }
            // 新增
            if (ListUtil.isNotEmpty(newWorkGroupIds))
            {
                if (newWorkGroupIds.size() > 0)
                {
                    for (String workGroupId : newWorkGroupIds)
                    {
                        Role workGroupRole = baseQuery.findRoleById(Long.parseLong(workGroupId));
                        emp.addTargetRoleLink(RoleLinkType.CONT, workGroupRole, DataTypeUtil.getCS(null), DataTypeUtil.getCS(null),
                            DataTypeUtil.getINT((1L)));
                    }
                }
            }

            // 删除比修改前多的工作组信息
            if (ListUtil.isNotEmpty(delWorkGroupIds))
            {
                if (delWorkGroupIds.size() > 0)
                {
                    for (int k = 0; k < delWorkGroupIds.size(); k++)
                    {
                        RimCoreRoleLink roleLink = (RimCoreRoleLink) delWorkGroupIds.get(k);
                        roleLinklist.remove(roleLink);
                        em.remove(roleLink);
                    }
                }
            }
       }
    
    private List<EntitysDTO> findEntitysDTOListByList(List<Role> list) throws Hl7Exception
    {
        List<EntitysDTO> entityList = new ArrayList<EntitysDTO>();
        if (ListUtil.isNotEmpty(list))
        {
            for (Role role : list)
            {
                EntitysDTO entitysDTO = new EntitysDTO();
                entitysDTO.setDepartment(this.findScopeEntityByRole(role));
                entitysDTO.setOrganization(this.findOrganizationByRole(role));
                PatientBaseInfoDTO patientBaseInfo =  this.findPlayEntityByRole(role);
                List<String> workGroupList = this.findWorkGroupIdsByRole(role);
                if (ListUtil.isNotEmpty(workGroupList))
                {
                    entitysDTO.setWorkgroupIds(workGroupList);
                }
                Employee empRole = (Employee) role;
                // 得到电子签名
                ED signImg = empRole.getProtectiveEquipmentText();
                if (null != signImg)
                {
                    if(patientBaseInfo == null)
                        patientBaseInfo = new PatientBaseInfoDTO();
                    patientBaseInfo.setSignImg(signImg.integrityCheck().byteArray());
                }
                entitysDTO.setPatientBaseInfo(patientBaseInfo);
                entityList.add(entitysDTO);
            }
        }
        log.info(entityList);
        return entityList;

    }
}
